#pragma once

#include <list>
#include "d3dx9math.h"

class Vector2 : public D3DXVECTOR2
{
public:
	Vector2(D3DXVECTOR2& v) {x = v.x; y = v.y;}
	Vector2() : D3DXVECTOR2() {x = 0; y = 0;}
	
	template <class T>
	Vector2(const T _x, const T _y) {x = (float)_x; y = (float)_y;}

	inline float Length() {return D3DXVec2Length(this);}
	inline Vector2* Normalize() {return static_cast<Vector2*>(D3DXVec2Normalize(this, this));}
	inline float Dot(const Vector2& b) {return D3DXVec2Dot(this, &b);}
};

class Vector3 : public D3DXVECTOR3
{
public:
	Vector3(D3DXVECTOR3& v) {x = v.x; y = v.y; z = v.z;}
	Vector3() : D3DXVECTOR3() {x = 0; y = 0; z = 0;}
	
	template <class T>
	Vector3(const T _x, const T _y, const T _z) {x = (float)_x; y = (float)_y; z = (float)_z;}

	inline Vector3(const class Vector4 &v);

	inline float Length() {return D3DXVec3Length(this);}
	inline Vector3* Normalize() {return static_cast<Vector3*>(D3DXVec3Normalize(this, this));}
	inline float Dot(const Vector3& b) {return D3DXVec3Dot(this, &b);}

	inline Vector3 Cross(const Vector3& b) const
	{
		Vector3 out;
		D3DXVec3Cross(&out, this, &b);
		return out;
	}
};


class Vector4 : public D3DXVECTOR4
{
public:
	Vector4(D3DXVECTOR4& v) {x = v.x; y = v.y; z = v.z; w = v.w;}
	Vector4() : D3DXVECTOR4() {x = 0; y = 0; z = 0; w = 1.f;}
	
	template <class T>
	Vector4(const T _x, const T _y, const T _z, const T _w) {x = (float)_x; y = (float)_y; z = (float)_z; w = (float)_w;}
	
	inline Vector4(const Vector3& v) {x = v.x; y = v.y; z = v.z; w = 1.f;}

	inline float Length() {return D3DXVec4Length(this);}
	inline Vector4* Normalize() {return static_cast<Vector4*>(D3DXVec4Normalize(this, this));}
	inline float Dot(const Vector4& b) {return D3DXVec4Dot(this, &b);}
};

inline Vector3::Vector3(const Vector4& v) {x = v.x; y = v.y; z = v.z;}

extern Vector3 g_forward;
extern Vector3 g_up;
extern Vector3 g_right;

extern Vector4 g_up4;
extern Vector4 g_right4;
extern Vector4 g_forward4;